#ifndef __PROC_H__
#define __PROC_H__

#include <global/header/types.h>

/* PROCESS MANIPULATING INTERFACE FOR BOTH LOCAL AND GLOBAL SCOPE */

#define PROC_TYPE_UNKNOWN 0
#define PROC_TYPE_KTHREAD 1
#define PROC_TYPE_UTHREAD 2
#define PROC_TYPE_LWIP    3

/* FOR SWITCHING THE PROC MONITOR */
extern int proc_monitor_toggle;

typedef struct proc_s *proc_t;
typedef void(*proc_entry_f)(void *arg);

/* Get the kernel-only Page Table */
physaddr_t proc_kvpt_get(void);

/* Start the process sub-system using the initial process */
void   proc_init(const char *name, int stack_size, proc_entry_f entry, void *arg);
/* Get self proc pointer */
proc_t proc_self(void);
/* Get/Set the type of self */
int  proc_type_get(void);
void proc_type_set(int type);
/* Create UNINIT process */
proc_t proc_create(const char *name, uint32_t level, int stack_size, physaddr_t vpt, proc_entry_f entry, void *arg);
/* Destroy UNINIT/ZOMBIE process */
void   proc_destroy(proc_t proc);

/* Attach new process to the scheduler */
void proc_attach(proc_t proc);
/* Turn self to ZOMBIE process */
void proc_exit(void);

/* Get/Set the private data pointer of self process */
void *proc_priv_get(void);
void  proc_priv_set(void *priv);

void proc_do_idle(void);
void proc_yield(void);
void proc_to_wait(void);

void proc_legacy_wait_pretend(void);
void proc_legacy_wait_try(void);
void proc_legacy_wait(void);
void proc_legacy_notify(proc_t proc);

/* The event-driven api */
typedef struct proc_event_s *proc_event_t;
typedef void (*proc_event_handler_f) (void *arg);

proc_event_t proc_self_dummy_event(void);
proc_event_t proc_event_local_create(int persistent, proc_event_handler_f handler, void *arg);
proc_event_t proc_event_create(int persistent, proc_t proc, proc_event_handler_f handler, void *arg);
int          proc_event_activate(proc_event_t event);
void         proc_event_process_irq_save(void);

#endif
